package com.management.demo.controller.management;

import cn.dev33.satoken.util.SaResult;
import com.management.demo.properties.WXProperties;
import com.management.demo.service.MinIOService;
import com.management.demo.utils.OrderNumberUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

@Tag(name = "文件管理")
@RestController
@RequestMapping("file")
public class FileController {

    private final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private MinIOService minIOService;

    @Value("${minio.bucket-name}")
    private String bucketName;

    @Autowired
    private WXProperties wxProperties;

    @Operation(summary = "上传文件到minio")
    @PostMapping("/minio/upload")
    public SaResult uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String objectName = OrderNumberUtils.generatePicName(file);
            minIOService.uploadFile(bucketName, objectName, file);
            return SaResult.ok().setData("https://minio.zhangyizhou.xyz/file/" + bucketName + "/" + objectName);
        } catch (Exception e) {
            e.printStackTrace();
            return SaResult.error("上传文件失败");
        }
    }

    @Operation(summary = "上传文件到系统盘")
    @PostMapping("/system/upload")
    public SaResult handleFileUpload(@RequestParam("file") MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();
            String extend = "";
            if (StringUtils.isNotBlank(originalFilename)) {
                extend = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String fileName = UUID.randomUUID().toString().toUpperCase().replace("-", "") + extend;
            File destFile = new File(wxProperties.getAvatarPath(), fileName);
            file.transferTo(destFile);
            return SaResult.ok().setData("http://47.121.182.69/images/" + fileName);
        } catch (IOException e) {
            e.printStackTrace();
            return SaResult.error("上传文件失败");
        }
    }

    @Operation(summary = "下载文件")
    @GetMapping("/download/{objectName}")
    public void downloadFile(@Parameter(description = "文件名") @PathVariable String objectName, HttpServletResponse response) {
        try (InputStream inputStream = minIOService.downloadFile(bucketName, objectName)) {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(objectName, StandardCharsets.UTF_8));
            IOUtils.copy(inputStream, response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            logger.error("下载文件失败");
            e.printStackTrace();
        }
    }

    @Operation(summary = "删除文件")
    @DeleteMapping("/delete/{objectName}")
    public SaResult deleteFile(@Parameter(description = "文件名")
                               @PathVariable String objectName) {
        try {
            minIOService.deleteFile(bucketName, objectName);
            return SaResult.ok().setData(true);
        } catch (Exception e) {
            e.printStackTrace();
            return SaResult.error("删除文件失败");
        }
    }

    @Operation(summary = "获得文件地址")
    @GetMapping("/url/{objectName}")
    public SaResult getObjectUrl(@Parameter(description = "文件名")
                                 @PathVariable String objectName) {
        try {
            String url = minIOService.getObjectUrl(objectName);
            return SaResult.ok().setData(url);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return SaResult.error("获取文件地址失败");
        }
    }
}
